package com.sleep.drug_traceability.service.impl;

import com.alibaba.fastjson.JSON;
import com.sleep.drug_traceability.dao.pojo.User;
import com.sleep.drug_traceability.service.LoginService;
import com.sleep.drug_traceability.service.UserService;
import com.sleep.drug_traceability.utils.JwtUtils;
import com.sleep.drug_traceability.vo.ErrorCode;
import com.sleep.drug_traceability.vo.Result;
import com.sleep.drug_traceability.vo.params.LoginParam;
import com.sleep.drug_traceability.vo.params.RegisterParam;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author Sleep-6000
 * @date 2022/4/23
 */
@Service
@Transactional
public class LoginServiceImpl implements LoginService {
    public static final String SALT = "Sleep$+-*/";

    @Autowired
    private UserService userService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public Result login(LoginParam loginParam) {
        //获取参数
        String username = loginParam.getUsername();
        String password = loginParam.getPassword();
        if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMsg());
        }
        //加密
        String pwd = DigestUtils.md5Hex(password + SALT);
        //获取用户信息
        User user = userService.findUser(username, pwd);
        if (user == null) {
            return Result.fail(ErrorCode.USR_PWD_NOT_EXIST.getCode(), ErrorCode.USR_PWD_NOT_EXIST.getMsg());
        }
        if (user.getUserStatus() == 0) {
            return Result.fail(ErrorCode.NO_PERMISSION.getCode(), ErrorCode.NO_PERMISSION.getMsg());
        }
        //使用 jwt 技术生成 token 返回给前端
        String token = JwtUtils.createToken(user.getId());
        redisTemplate.opsForValue().set("TOKEN_" + token, JSON.toJSONString(user), 1, TimeUnit.DAYS);
        Map<String, String> map = new HashMap<>(3);
        map.put("token", token);
        map.put("id",String.valueOf(user.getId()));
        map.put("type", String.valueOf(user.getType()));
        map.put("isPerfect",String.valueOf(user.getIsPerfect()));

        return Result.success(map);
    }

    @Override
    public User checkToken(String token) {
        if (StringUtils.isBlank(token)) {
            return null;
        }
        Map<String, Object> map = JwtUtils.checkToken(token);
        if (map == null) {
            return null;
        }
        String userJson = redisTemplate.opsForValue().get("TOKEN_" + token);
        if (StringUtils.isBlank(userJson)) {
            return null;
        }
        return JSON.parseObject(userJson, User.class);
    }

    @Override
    public Result logout(String token) {
        redisTemplate.delete("TOKEN_" + token);
        return Result.success(null);
    }

    @Override
    public Result register(RegisterParam registerParam) {
        String username = registerParam.getUsername();
        String password = registerParam.getPassword();
        int type = registerParam.getType();
        String phoneNumber = registerParam.getPhoneNumber();
        if (StringUtils.isBlank(username) || StringUtils.isBlank(password) || StringUtils.isBlank(phoneNumber)) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMsg());
        }
        if (type > 3 || type <= 0) {
            return Result.fail(ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TYPE_ERROR.getMsg());
        }

        User user = userService.findUserByUsername(username);
        if (user != null) {
            return Result.fail(ErrorCode.USR_EXIT.getCode(), ErrorCode.USR_EXIT.getMsg());
        }

        user = new User();
        user.setUsername(username);
        user.setPwd(DigestUtils.md5Hex(password + SALT));
        user.setType(type);
        user.setPhoneNumber(phoneNumber);
        user.setCreateDate(System.currentTimeMillis());
        user.setUserStatus(1);
        user.setIsPerfect(0);
        userService.save(user);

        String token = JwtUtils.createToken(user.getId());
        redisTemplate.opsForValue().set("TOKEN_" + token, JSON.toJSONString(user), 1, TimeUnit.DAYS);

        return Result.success(token);
    }
}
